package org.csu.gp_store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.csu.gp_store.entity.Account;
import org.csu.gp_store.mapper.AccountMapper;
import org.csu.gp_store.service.AccountService;
import org.csu.gp_store.util.TokenUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    AccountMapper accountMapper;

    @Override
    public IPage<Account> getAccountList() {
        IPage<Account> page = new Page<>(0, 5);
        return accountMapper.selectPage(page, null);
    }

    @Override
    public Account getAccount(@NotNull Long username) {
        return accountMapper.selectById(username);
    }

    @Override
    public Account getAccountByEmail(@NotNull String email) {
        LambdaQueryWrapper<Account> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Account::getEmail, email);
        List<Account> accountList = accountMapper.selectList(lambdaQueryWrapper);
        if (accountList.size() == 1) {
            return accountList.get(0);
        } else {
            return null;
        }
    }

    @Override
    public boolean idExist(@NotNull Long AccountID) {
        Account account = getAccount(AccountID);
        return account != null;
    }

    @Override
    public boolean nameExist(@NotNull String name) {
        LambdaQueryWrapper<Account> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Account::getName, name);
        List<Account> accountList = accountMapper.selectList(lambdaQueryWrapper);
        return !accountList.isEmpty();
    }

    @Override
    public boolean emailExist(@NotNull String email) {
        LambdaQueryWrapper<Account> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Account::getEmail, email);
        List<Account> accountList = accountMapper.selectList(lambdaQueryWrapper);
        return !accountList.isEmpty();
    }

    @Override
    public String userLogin(@NotNull String username, @NotNull String password, @NotNull String method) {
        Account account;
        LambdaQueryWrapper<Account> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Account::getEmail, username);
        account = accountMapper.selectOne(lambdaQueryWrapper);
        if (account == null || !account.getPassword().equals(password)) {
            return null;
        }
        return TokenUtil.createToken(account.getAccountID().toString());
    }

//    @Override
//    public int insertRandomCode(@NotNull String username, @NotNull String verifyCode) {
//        if (!idExist(username)) {
//            return 0;
//        }
//        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
//        updateWrapper.eq("AccountID", username);
//        updateWrapper.set("verifyCode", verifyCode);
//        return accountMapper.update(null, updateWrapper);
//    }

    @Override
    public int createNewUser(Account account) {
        if (nameExist(account.getName())||emailExist(account.getEmail())) {
            return 0;
        }
        return accountMapper.insert(account);
    }

    @Override
    public int modifyInfo(Account account) {
        if (!idExist(account.getAccountID())) {
            return 0;
        }
        return accountMapper.updateById(account);
    }

    @Override
    public int cancelAccount(@NotNull Long username, @NotNull String password, @NotNull String email) {
        if (!idExist(username)) {
            return 0;
        }
        Account account = getAccount(username);
        if (account.getPassword().equals(password) && account.getEmail().equals(email)) {
            UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("AccountID", username);
            updateWrapper.set("status", 2);
            return accountMapper.update(null, updateWrapper);
        } else {
            return 0;
        }
    }

    @Override
    public int cancelSubmit(@NotNull Long username) {
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("AccountID", username);
        updateWrapper.set("status", 4);
        return accountMapper.update(null, updateWrapper);
    }

    @Override
    public boolean standardAccount(@NotNull String AccountID) {
        String regEx = "[ `~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(AccountID);
        if (m.find() || AccountID.length() > 20 || AccountID.length() < 4 || !Character.isLetter(AccountID.charAt(0))) {
            return false;
        }
        return true;
    }

    @Override
    public boolean standardPassword(@NotNull String password) {
        boolean hasLetter = false;
        boolean hasNumber = false;
        if (password.length() < 8 || password.length() > 20) {
            return false;
        }
        for (int i = 0; i < password.length(); i++) {
            if (Character.isLetter(password.charAt(i))) {
                hasLetter = true;
            }
            if (Character.isDigit(password.charAt(i))) {
                hasNumber = true;
            }
        }
        return hasLetter && hasNumber;
    }
}
